package com.stylefeng.guns.modular.system.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.stylefeng.guns.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.common.constant.state.MenuStatus;
import com.stylefeng.guns.common.exception.BizExceptionEnum;
import com.stylefeng.guns.common.exception.BussinessException;
import com.stylefeng.guns.common.persistence.dao.MenuMapper;
import com.stylefeng.guns.common.persistence.model.Menu;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.dao.MenuDao;
import com.stylefeng.guns.modular.system.service.IMenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

/**
 * 菜单服务
 *
 * @author fengshuonan
 * @date 2017-05-05 22:20
 */
@Service
public class MenuServiceImpl implements IMenuService {

    @Resource
    MenuMapper menuMapper;

    @Resource
    MenuDao menuDao;

    @Override
    public void delMenu(Long menuId) {

        //删除菜单
        this.menuMapper.deleteById(menuId);

        //删除关联的relation
        this.menuDao.deleteRelationByMenu(menuId);
    }

    @Override
    public void delMenuContainSubMenus(Long menuId) {

        Menu menu = menuMapper.selectById(menuId);

        //删除当前菜单
        delMenu(menuId);

        //删除所有子菜单
        Wrapper<Menu> wrapper = new EntityWrapper<>();
        wrapper = wrapper.like("pcodes", "%[" + menu.getCode() + "]%");
        List<Menu> menus = menuMapper.selectList(wrapper);
        for (Menu temp : menus) {
            delMenu(temp.getId());
        }
    }

    @Override
    @Transactional
    public void addAddDeleteUpdate(Long menuId) {
        Menu menu = menuMapper.selectById(menuId);
        String menuCode = menu.getCode();
        String menuName = menu.getName();
        String menuUrl = menu.getUrl();

        Menu addButton = new Menu();
        addButton.setNum(1);
        addButton.setPcode(menu.getId() +"");
        addButton.setCode(menuCode + "_add");
        addButton.setName("增加");
        addButton.setUrl(menuUrl + "/add");
        addButton.setStatus(MenuStatus.ENABLE.getCode());
        addButton.setIsmenu(0);
        menuSetPcode(addButton);

        Menu delButton = new Menu();
        delButton.setNum(2);
        delButton.setPcode(menu.getId() +"");
        delButton.setCode(menuCode + "_delete");
        delButton.setName("删除");
        delButton.setUrl(menuUrl + "/delete");
        delButton.setStatus(MenuStatus.ENABLE.getCode());
        delButton.setIsmenu(0);
        menuSetPcode(delButton);

        Menu updateBtn = new Menu();
        updateBtn.setNum(3);
        updateBtn.setPcode(menu.getId() +"");
        updateBtn.setCode(menuCode + "_update");
        updateBtn.setName("更新");
        updateBtn.setUrl(menuUrl + "/update");
        updateBtn.setStatus(MenuStatus.ENABLE.getCode());
        updateBtn.setIsmenu(0);
        menuSetPcode(updateBtn);

        if (ToolUtil.isNotEmpty(ConstantFactory.me().getMenuNameByCode(delButton.getCode())) ||
                ToolUtil.isNotEmpty(ConstantFactory.me().getMenuNameByCode(delButton.getCode())) ||
                ToolUtil.isNotEmpty(ConstantFactory.me().getMenuNameByCode(delButton.getCode()))) {
            throw new BussinessException(BizExceptionEnum.EXISTED_THE_MENU);
        }

        menuMapper.insert(addButton);
        menuMapper.insert(delButton);
        menuMapper.insert(updateBtn);
    }


    /**
     * 根据请求的父级菜单编号设置pcode和层级
     */
    private void menuSetPcode(@Valid Menu menu) {
        if (ToolUtil.isEmpty(menu.getPcode()) || menu.getPcode().equals("0")) {
            menu.setPcode("0");
            menu.setPcodes("[0],");
            menu.setLevels(1);
        } else {
            int code = Integer.parseInt(menu.getPcode());
            Menu pMenu = menuMapper.selectById(code);
            Integer pLevels = pMenu.getLevels();
            menu.setPcode(pMenu.getCode());

            //如果编号和父编号一致会导致无限递归
            if (menu.getCode().equals(menu.getPcode())) {
                throw new BussinessException(BizExceptionEnum.MENU_PCODE_COINCIDENCE);
            }

            menu.setLevels(pLevels + 1);
            menu.setPcodes(pMenu.getPcodes() + "[" + pMenu.getCode() + "],");
        }
    }
}
